package com.keguoyu.easymvp.ioc.internal.util

import com.android.build.api.transform.*
import com.google.common.reflect.TypeToken
import com.keguoyu.easymvp.ioc.internal.Invocation
import java.io.File
import java.io.Reader

fun TransformInput.loopAllFiles(
    outputProvider: TransformOutputProvider,
    task: (File, File, Status?) -> Unit):Set<File> {
    val roots = HashSet<File>()
  directoryInputs.forEach { directoryInput ->
    val changedFiles = directoryInput.changedFiles
    val dest = outputProvider.getContentLocation(directoryInput.name,
        directoryInput.contentTypes, directoryInput.scopes,
        Format.DIRECTORY)
    val root = directoryInput.file
      roots.add(root)
    root.walkTopDown().forEach fileLoop@{
      if (!it.isFile) {
        return@fileLoop
      }
      task(it, it.toDestFile(root, dest), changedFiles[it])
    }
  }
    return roots
}

fun TransformInput.loopAllJars(
    outputProvider: TransformOutputProvider,
    task: (JarInput, File) -> Unit) {
  jarInputs.forEach fileLoop@{ jarInput ->
    // 重命名输出文件（同目录copyFile会冲突）
    var jarName = jarInput.name
    if (jarName.endsWith(".jar")) {
      jarName = jarName.substring(0, jarName.length - 4)
    }
    //生成输出路径
    val dest = outputProvider.getContentLocation(jarName,
        jarInput.contentTypes, jarInput.scopes, Format.JAR)
    task(jarInput, dest)
  }
}

fun File.toDestFile(root: File, dest: File): File {
  val path = absolutePath.substring(root.absolutePath.length)
  return File(dest, path)
}

fun Reader.readInvocationList(): List<Invocation> {
  val invocations = mutableListOf<Invocation>()
  this.forEachLine { line ->
    invocations.addAll(GSON.fromJson(line, object : TypeToken<List<Invocation>>() {}.type))
  }
  return invocations
}

/**
 * 解析invoker_info文件
 * 返回值: Pair(invocationList, allClassSetFromInvocation)
 */
fun Reader.parseInvocation(): Pair<List<Invocation>, Set<String>> {
  val allClassSet = mutableSetOf<String>()
  val invocationList = mutableListOf<Invocation>()
  forEachLine { line ->
    val invocations: List<Invocation> =
      GSON.fromJson(line, object : TypeToken<List<Invocation>>() {}.type)
    invocations.forEach { invocation ->
      allClassSet.add(invocation.target.className)
      allClassSet.add(invocation.invoker.className)
      allClassSet.addAll(invocation.params)
    }
    invocationList.addAll(invocations)
  }
  return Pair(invocationList, allClassSet)
}